x86 paging_domctl: reinstates the breaks in the flow control (and
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 25 Jun 2010 14:44:58 +0000 (15:44 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 25 Jun 2010 14:44:58 +0000 (15:44 +0100)
folds two identical cases together) and fixes the memory leak that was
causing a crash.

Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>
xen/arch/x86/mm/paging.c
xen/arch/x86/mm/shadow/common.c

index b5ef2c6eb018aa1189d092e41acb5ec9d161592e..66548ef600df396f83ab0d12fb0b15de3e786ea0 100644 (file)
@@ -700,23 +700,21 @@ int paging_domctl(struct domain *d, xen_domctl_shadow_op_t *sc,
      */
     switch ( sc->op )
     {
+
+    case XEN_DOMCTL_SHADOW_OP_ENABLE:
+        if ( !(sc->mode & XEN_DOMCTL_SHADOW_ENABLE_LOG_DIRTY) )
+            break;
+        /* Else fall through... */
     case XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY:
         if ( hap_enabled(d) )
             hap_logdirty_init(d);
         return paging_log_dirty_enable(d);
 
-    case XEN_DOMCTL_SHADOW_OP_ENABLE:
-        if ( sc->mode & XEN_DOMCTL_SHADOW_ENABLE_LOG_DIRTY )
-        {
-            if ( hap_enabled(d) )
-                hap_logdirty_init(d);
-            return paging_log_dirty_enable(d);
-        }
-
     case XEN_DOMCTL_SHADOW_OP_OFF:
         if ( paging_mode_log_dirty(d) )
             if ( (rc = paging_log_dirty_disable(d)) != 0 )
                 return rc;
+        break;
 
     case XEN_DOMCTL_SHADOW_OP_CLEAN:
     case XEN_DOMCTL_SHADOW_OP_PEEK:
index 1c85cb23d1c7f0a86a952fd7d5819ff41c3a5ccc..a42de64725606b17028fcf9905100f366c6af4e5 100644 (file)
@@ -3241,9 +3241,12 @@ void shadow_teardown(struct domain *d)
         {
             int i;
             mfn_t *oos_snapshot = v->arch.paging.shadow.oos_snapshot;
-            for(i = 0; i < SHADOW_OOS_PAGES; i++)
+            for ( i = 0; i < SHADOW_OOS_PAGES; i++ )
                 if ( mfn_valid(oos_snapshot[i]) )
+                {
                     shadow_free(d, oos_snapshot[i]);
+                    oos_snapshot[i] = _mfn(INVALID_MFN);
+                }
         }
 #endif /* OOS */
     }
@@ -3395,17 +3398,23 @@ static int shadow_one_bit_disable(struct domain *d, u32 mode)
 #endif
                 make_cr3(v, pagetable_get_pfn(v->arch.guest_table));
 
+#if (SHADOW_OPTIMIZATIONS & SHOPT_OUT_OF_SYNC) 
+            {
+                int i;
+                mfn_t *oos_snapshot = v->arch.paging.shadow.oos_snapshot;
+                for ( i = 0; i < SHADOW_OOS_PAGES; i++ )
+                    if ( mfn_valid(oos_snapshot[i]) )
+                    {
+                        shadow_free(d, oos_snapshot[i]);
+                        oos_snapshot[i] = _mfn(INVALID_MFN);
+                    }
+            }
+#endif /* OOS */
         }
 
         /* Pull down the memory allocation */
         if ( sh_set_allocation(d, 0, NULL) != 0 )
-        {
-            // XXX - How can this occur?
-            //       Seems like a bug to return an error now that we've
-            //       disabled the relevant shadow mode.
-            //
-            return -ENOMEM;
-        }
+            BUG(); /* In fact, we will have BUG()ed already */
         shadow_hash_teardown(d);
         SHADOW_PRINTK("un-shadowing of domain %u done."
                        "  Shadow pages total = %u, free = %u, p2m=%u\n",